// Module..: NUM_CONVERSION.C
// Original: September 2008
// Version.: 1.0
// Compiler: CodeRed ARM
// Chip....: NXP LPC
// Date....: July 2012
// Author..: Hyla
//-----------------------------------------------------------------------------

#include "num_conversion.h"
#include <string.h>
//-----------------------------------------------------------------------------

/*__flash*/ U08 NC_HEX_ARRAY[] = "0123456789ABCDEF";
//-----------------------------------------------------------------------------

char nc_buffer[NC_BUFFER_LENGTH]; // Conversion buffer
U08 nc_format_buffer[NC_BUFFER_LENGTH]; // Format buffer

static U08 nc_int_digits[8];
static U08 nc_dec_digits[6];
//-----------------------------------------------------------------------------

char * nc_format(char * source_ptr,U08 digits)
{
  U08 len = strlen(source_ptr);
  char * dest_ptr = (char *)&nc_format_buffer;

  // Fillup loop
  while (digits-- > len)
  {
    *dest_ptr++ = NC_FILL_CHAR;
  }

  // Copy loop
  while (len--)
  {
    *dest_ptr++ = *source_ptr++;
  }

  *dest_ptr = 0; // Terminate format string

  return (char *)&nc_format_buffer;
}
//-----------------------------------------------------------------------------

char * nc_U08_to_str(U08 value,U08 digits)
{
  char * pstr = nc_buffer;

  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_S08_to_str(S08 signed_value,U08 digits)
{
  char * pstr = nc_buffer;
  U08 value;

  if (signed_value < 0)
  {
    *pstr++ = '-';
    value = -signed_value;
  }
  else
  {
    value = signed_value;
  }

  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_U08_to_hex(U08 value)
{
  char * pstr = nc_buffer;

  *pstr++ = NC_HEX_ARRAY[value >> 4];
  *pstr++ = NC_HEX_ARRAY[value & 0x0F];
  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_U08_to_bin(U08 value)
{
  char * pstr = nc_buffer;
  U08 n;

  for (n = 7; n < 8; n--)
  {
    if (value & (1 << n))
    {
      *pstr++ = '1';
    }
    else
    {
      *pstr++ = '0';
    }
  }

  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_U16_to_str(U16 value,U08 digits)
{
  char * pstr = nc_buffer;

  if (value >= 10000) *pstr++ = ('0' + (value / 10000));
  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10)*pstr++ = ('0' + (value % 100 / 10));
  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_U16_to_bin(U16 value)
{
  char * pstr = nc_buffer;
  U16 n;

  for (n = 15; n < 16; n--)
  {
    if (value & (1 << n))
    {
      *pstr++ = '1';
    }
    else
    {
      *pstr++ = '0';
    }
  }

  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_S16_to_str(S16 signed_value,U08 digits)
{
  char * pstr = nc_buffer;
  U16 value;

  if (signed_value < 0)
  {
    *pstr++ = '-';
    value = -signed_value;
  }
  else
  {
    value = signed_value;
  }

  if (value >= 10000) *pstr++ = ('0' + (value / 10000));
  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_U16_to_hex(U16 value)
{
  char * pstr = nc_buffer;
  tMEM16 data;

  data.word = value;

  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) & 0x0F];

  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) & 0x0F];

  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_U32_to_str(U32 value,U08 digits)
{
  char * pstr = nc_buffer;

  if (value >= 1000000000) *pstr++ = ('0' + (value / 1000000000));
  if (value >= 100000000) *pstr++ = ('0' + (value % 1000000000 / 100000000));
  if (value >= 10000000) *pstr++ = ('0' + (value % 100000000 / 10000000));
  if (value >= 1000000) *pstr++ = ('0' + (value % 10000000 / 1000000));
  if (value >= 100000) *pstr++ = ('0' + (value % 1000000 / 100000));
  if (value >= 10000) *pstr++ = ('0' + (value % 100000 / 10000));
  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));

  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_S32_to_str(S32 signed_value,U08 digits)
{
  char * pstr = nc_buffer;
  U32 value;

  if (signed_value < 0)
  {
    *pstr++ = '-';
    value = -signed_value;
  }
  else
  {
    value = signed_value;
  }

  if (value >= 1000000000) *pstr++ = ('0' + (value / 1000000000));
  if (value >= 100000000) *pstr++ = ('0' + (value % 1000000000 / 100000000));
  if (value >= 10000000) *pstr++ = ('0' + (value % 100000000 / 10000000));
  if (value >= 1000000) *pstr++ = ('0' + (value % 10000000 / 1000000));
  if (value >= 100000) *pstr++ = ('0' + (value % 1000000 / 100000));
  if (value >= 10000) *pstr++ = ('0' + (value % 100000 / 10000));
  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));

  *pstr++ = ('0' + (value % 10));
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
//-----------------------------------------------------------------------------

char * nc_U32_to_hex(U32 value)
{
  char * pstr = nc_buffer;
  tMEM32 data;

  data.dword = value;

  *pstr++ = NC_HEX_ARRAY[(data.byte[3]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[3]) & 0x0F];

  *pstr++ = NC_HEX_ARRAY[(data.byte[2]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[2]) & 0x0F];

  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) & 0x0F];

  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) >> 4];
  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) & 0x0F];

  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_U32_to_bin(U32 value)
{
  char * pstr = nc_buffer;
  U32 n;

  for (n = 31; n < 32; n--)
  {
    if (value & (1 << n))
    {
      *pstr++ = '1';
    }
    else
    {
      *pstr++ = '0';
    }
  }

  *pstr = 0;

  return (nc_buffer);
}
//-----------------------------------------------------------------------------

char * nc_float_to_str(float value,U08 decimals,U08 digits)
{
  S08 n;
  U08 int_count;
  U08 dec_count;
  float dec_part;
  U32 int_part;
  char * pstr = nc_buffer;

  if (decimals > 5)
  {
    decimals = 5;
  }

  if (value < 0.0)
  {
    *pstr++ = '-';
    value = -value;
  }

  int_part = value;
  dec_part = value - int_part;
  int_count = 0;
  dec_count = 0;

  if (int_part == 0)
  {
    *pstr++ = '0';
  }

  while (int_part > 0)
  {
    nc_int_digits[int_count] = int_part % 10;
    int_part = int_part - nc_int_digits[int_count];

    if (int_part > 0)
    {
      int_part = int_part / 10;
    }

    int_count++; // go to the next digit
  }

  while (dec_count < decimals)
  {
    dec_part = dec_part * 10.0;
    nc_dec_digits[dec_count] = dec_part;

    if (nc_dec_digits[dec_count] > 0)
    {
      dec_part = dec_part - nc_dec_digits[dec_count];
    }

    dec_count++;
  }

  for (n = int_count - 1; n > -1; n--)
  {
    *pstr++ = 48 + nc_int_digits[n];
  }

  *pstr++ = '.';

  for (n = 0; n < dec_count; n++)
  {
    *pstr++ = 48 + nc_dec_digits[n];
  }

  // Terminate string
  *pstr = 0;

  if (!digits) // If digits = 0, then return buffer start
  {
    return nc_buffer;
  }
  else // Do formatted output
  {
    return nc_format(nc_buffer,digits);
  }
}
